package com.beeasy.hzbpm.cron;

import cn.hutool.core.util.StrUtil;
import com.beeasy.hzbpm.bean.Lock;
import com.beeasy.hzbpm.bean.Notice;
import com.beeasy.hzbpm.entity.BpmData;
import com.beeasy.hzbpm.entity.BpmInstance;
import com.beeasy.hzbpm.service.BpmService;
import com.github.llyb120.nami.cron.ICron;
import com.mongodb.client.MongoCollection;
import org.bson.Document;

import java.util.Date;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static com.beeasy.hzbpm.bean.MongoService.db;
import static com.github.llyb120.json.Json.o;

public class BpmNotify implements ICron {

    @Override
    public void run() throws Exception {
        MongoCollection<Document> col = db.getCollection("bpmInstance");
        Date date = new Date();
        col.find(o(
            "state", "流转中",
            "currentNodes.minTimeout", o("$lt", date),
            "currentNodes.maxTimeout", o("$gt", date)
        ).toBson()).forEach((Consumer<? super Document>) e -> {
            //只提醒需要提醒的字段
            String id = e.getObjectId("_id").toString();
            try {
                Lock.lock(id);
                BpmService service = BpmService.ofIns(e);
            for (BpmInstance.CurrentNode cNode : service.ins.currentNodes) {
                    //可以提醒
                    if(date.after(cNode.minTimeout) && date.before(cNode.maxTimeout)){

                        String msg = String.format("您有未处理的代办任务，请尽快处理。流程id：%s，流程名：%s",service.ins.id,service.ins.bpmName);
                        if(!cNode.nodeId.startsWith("StartEvent")){
                            //主办人无论如何都要提醒
                            //消息将来可能需要重新配置
                            Notice.sendSystem(cNode.mainUsers.keySet(), msg, service.ins._id.toString());
                        }
                        //过滤出该提醒的人
                        BpmData.Node node = service.getNode(cNode.nodeId);
                        //如果为会签节点的经办人，则需要判断是否已经会签完毕，会签完毕就不提醒
                        // 是否可以会签
                        boolean canSign = node.flow != null && (StrUtil.equals(node.flow.countersign, "allow") || StrUtil.equals(node.flow.countersign, "force"));
                        if(canSign){
                            // 未会签完毕
                            //全部经办人
                            Set<String> supportUsers = cNode.supportUsers.keySet();

                            //已处理任务的经办人
                            Set<String> oversUser = service.ins.signs.stream()
                                    .filter(ee -> ee.nodeId.equals(node.id) && ee.over)
                                    .map(eee -> eee.uid)
                                    .collect(Collectors.toSet());
                            supportUsers.removeAll(oversUser);

                            if(!cNode.nodeId.startsWith("StartEvent")){
                                Notice.sendSystem(supportUsers, msg, service.ins._id.toString());
                            }
                        }

                        //更新提醒间隔
                        cNode.minTimeout = cNode.timeFormat(cNode.minTimeout, node.timeout.stepValue, node.timeout.stepUnit);
                        service.saveIns("currentNodes");
                    }
                }
            }
            catch (Exception ee){ }
            finally {
                Lock.unlock(id);
            }
        });
    }

}
